\ armasm.part3 of 4 v1.0

private:

\ Data operations

: (OP)  INST_MS 2@  DOR DOR  
   2SWAP 10 DLSHIFT DOR 2SWAP 
   0C DLSHIFT DOR CODE, RESET ;

: OP  CREATE , , DOES> 2@ (OP) ;

: OPS  10 0 DO  
   I 0 15 DLSHIFT OP  LOOP ;

public:

OPS AND, EOR, SUB, RSB, ADD, ADC, SBC, RSC, xx1 xx2 xx3 xx4 ORR, xx5 BIC, xx6

private:

: SET  100000.  INSTOR! ;

public:

: TST,  R0 -2ROT SET xx1 ;      
: TEQ,  R0 -2ROT SET xx2 ;
: CMP,  R0 -2ROT SET xx3 ;      
: CMN,  R0 -2ROT SET xx4 ;
: MOV,  R0 2SWAP xx5 ;          
: MVN,  R0 2SWAP xx6 ;

: MUL,  8 DLSHIFT INST_LS @ 90 OR
  INST_MS @ DOR DOR 2SWAP 10 
  DLSHIFT DOR CODE,  RESET ;

: MLA,  0C DLSHIFT 200090. DOR
  INSTOR!  MUL,  ;


\ Shifts
: LSL  8 DLSHIFT 10. DOR  INSTOR! ;   
: ASL  LSL ;
: #LSL  0 7 DLSHIFT  INSTOR! ;   
: #ASL  #LSL ;
: LSR  8 DLSHIFT 30. DOR  INSTOR! ;
: #LSR  0 7 DLSHIFT 20. DOR  INSTOR! ;
: ASR  8 DLSHIFT 50. DOR  INSTOR! ;
: #ASR  0 7 DLSHIFT 40. DOR  INSTOR! ;
: ROR  8 DLSHIFT 70. DOR  INSTOR! ;
: #ROR  0 7 DLSHIFT 60. DOR  INSTOR! ;
: RRX  0 #ROR ;

private:

\ Immediate constants

: MINIMIZE  ( x1. -- x2. u )   
\ minimize unsigned value of 
\ x1 by rotation
   2DUP 100. UD< IF  0 EXIT  THEN   
 \ stop if already a usable constant
   0 -ROT  ( rotation#  minFound. )
   2DUP
   10 1 DO  \ try each rotation
       2 DLROTATE  2OVER 2OVER UD>
       IF  2NIP ROT DROP  I  -ROT 2DUP
      THEN
   LOOP 2DROP
   ROT ;

: IMM  INST_MS  DUP 
  @ 200 XOR  SWAP ! ;  

public:

\ NOTE: Use  # for single cell values
\ and #. for double-cell values

: #.  ( dst. src. n. -- )
  MINIMIZE  0 2OVER 0FF. UD> 
  ABORT" immediate constant too large"  
  IMM DROP 8 LSHIFT 0 INSTOR! ; 

: # ( dst. src. n -- )   S>D #.  ;


\ Addressing modes

: @- ; IMMEDIATE               
: @+   800000. INSTOR! ;
: -@  1000000. INSTOR! ;     
: +@  1800000. INSTOR! ;
: -@!  1200000. INSTOR! ;     
: +@!  1A00000. INSTOR! ;

private:

: OFFSET   DUP FFF U> 
 ABORT" immediate offset too large"
  IMM 0 INSTOR!  0.   ;

public:

: #@-  OFFSET @- ;             
: #@+  OFFSET @+ ;
: #-@  OFFSET -@ ;              
: #+@  OFFSET +@ ;
: #-@!  OFFSET -@! ;             
: #+@!  OFFSET +@! ;
: 0@   0 #+@ ;

\ Loading and storing

: BYTE  400000. INSTOR! ;
: LDR,  IMM 4100000. (OP) ;
: STR,  IMM 4000000. (OP) ;

: PCR  HERE 8 + -  DUP ABS FFF > 
  ABORT" address out of range"
  DUP 0< IF  NEGATE #-@  
  ELSE #+@  THEN  PC  2SWAP ;

: PUSH,  4 #-@! STR, ;
: POP,  4 #@+ LDR, ;

private:

: MODES  4 0 DO  I 0  17
  DLSHIFT  2CONSTANT  LOOP ;
: STACKS  4 0 DO  I 0  17 
  DLSHIFT  800 OR  2CONSTANT  
  LOOP ;

public:

MODES  DA IA DB IB
STACKS ED EA FD FA

: @!  200000. INSTOR! ;
: ^  400000. INSTOR! ;

private:

: (LDSTM)  INST_MS 2@  DOR 
    DOR DOR  2SWAP 10 DLSHIFT 
    DOR CODE,  RESET ;

public:

: LDM,  DUP 800 AND 
  IF  180 XOR  THEN  
  8100000. (LDSTM) ;

: STM,  8000000. (LDSTM) ;

: {  20. ;
: }  0.  BEGIN  2OVER 20. D<> WHILE  
  1. 2ROT DROP DLSHIFT DOR  
  REPEAT  2NIP ;

private:

\ Branches

: >BRANCH ( targ here -- DAdr. ) 
  >-< S>D 2 DRSHIFT 2. D- 00FF AND ; 

: !BRANCH ( targ targ here DAdr. -- )
  2SWAP >BRANCH DOR
  DSWAPENDS ROT 2! ;

: JOIN ( targ here -- )
  OVER TUCK
  2@ DSWAPENDS !BRANCH ;

: (B) ( branchTarg opCode. -- ) 
  ROT HERE SWAP  >BRANCH  
  INST_MS 2@  DOR  DOR 
  CODE,  RESET ;

public:
 
: B, ( branchTarget -- )
  A000000. (B) ;
: BL, ( branchTarget -- ) 
  B000000. (B) ;

: RET,  PC LR SET MOV, ;

\ [NAB]
: BX,  12FFF10. INST_MS 2@ 
  DOR  DOR  CODE,  RESET ;
